package com.xunfang;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 *   自动装配
 *      01  好多东西内置了  boot 启动后 可以直接使用
 *          springmvc 就内置了  dispatchServlet
 *          redis中   就内置了  RedisTemplate
 *      内置好处就是 自动装配  可以直接使用 (预制菜)
 *
 *    boot的自动准配的流程:
 *     01 @SpringBootApplication  加载注解
 *           @SpringBootConfiguration      配置类
 *           @ComponentScan                扫描类型
 *           @EnableAutoConfiguration      开启自动配置
 *               @EnableAutoConfiguration 这个里面 进行加载 @Import(AutoConfigurationImportSelector.class)
 *
 *          这个类中会加载 AutoConfigurationImportSelector  这个类  这个类中会去加载
 *             3.4.1 版本    194行中    getCandidateConfigurations  方法  META-INF/spring/下面的配置文件
 *             2.3.12 版本   177行中    getCandidateConfigurations  方法  META-INF/spring.factories配置文件
 *
 *    02 加载 spring.factories 这个文件
 *             自动配置的类
 *                           RedisAutoConfiguration  redis的配置类
 *                           DataSourceAutoConfiguration  数据库连接的对象
 *
 *    03    DataSourceAutoConfiguration 这个类干啥
 *           1、读取yaml 配置
 *                 @EnableConfigurationProperties(DataSourceProperties.class)
 *                 读取解析yaml 中的 jdbc的 配置
 *           2、初始化对象 添加到ioc容器中
 *                  一般初始化连接 \初始化 xxxTemplate 添加到ioc容器中
 *
 *    04 启动完毕后
 *                springboot容器中有 准配的类 可以直接使用
 *
 *   学习上面有什么作用?
 *      01  面试 面试官喜欢问
 *      02  我能不能在项目中也这么用?
 *           01 在 META-INF/spring.factories 配置自己的 GkAutoConfiguration
 *           02 在 GkAutoConfiguration 中加载
 *                       yaml 中的 gk的一些配置
 *                       初始化gkTemplate
 *           03 可以直接使用 gkTemplate 进行操作
 */
@MapperScan("com.xunfang.mapper")  //扫描 mapper 包 创建对象 添加IOC容器中
@SpringBootApplication
public class Application {

    public static void main(String[] args) {

        //容器的启动 返回一个容器
        ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args);

        //可以获取容器中的bean 对象
        applicationContext.getBean("XXX");

        //有多少个对象
        int beanDefinitionCount = applicationContext.getBeanDefinitionCount();

        //容器中 有哪些对象的名字
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();

        /**
         *    把一个对象添加到ioc容器中的几种方式 ?
         *
         *    01  扫描注解  @ComponentScan  + @controller + @Service       正常开发的使用
         *    02  配置注解  @Configuration  + 方法上面 + @Bean 注解         配置中的使用
         *    03  xml配置文件  + Bean + 扫描
         *    04  @Import  这个 可以把一个Class 文件添加到IOC容器中          自动装配中使用
         *    05  实现接口  BeanFactory 实现接口 重写方法  把对象导入到ioc容器中  (第三方框架整合中使用 )
         *    06  自己手动进行注册
         *            前置转换器中可以                                      底层代码实现 原理中使用
         *
         */
    }

}